import QtQuick 2.0
import FileIO 1.0
import Process 1.0

Item {
    id: archiveInstaller

    signal finished()
    signal error()

    property string outputDir

    readonly property alias isRunning: process.isRunning
    property var progress

    readonly property string deleteFiles: outputDir + "/deletefiles.txt"


    Process {
        id: process

        property string archive

        property string lastOutput
        property int filesListCount: 0
        property int filesUnarchivedCount: 0

        property int mode: modeIdle
        readonly property int modeIdle: 0
        readonly property int modeList: 1
        readonly property int modeUnarchive: 2

        workingDirectory: outputDir


        onFinished: {
            console.log("unzip exit code: " + code)

            if (code === 0) {
                onProcessFinished()
            } else {
                ui.log(lastOutput)
                archiveInstaller.error()
            }
        }

        onOutputRead: {
            lastOutput = output
            let filesCount = 0
            for (let line of output.split("\n")) {
                if (line.match('/')) {
                    ++filesCount
                }
                if (line.match('error')) {
                    ui.log(line)
                }
            }

            switch (mode) {
                case modeList:
                    filesListCount += filesCount
                    break

                case modeUnarchive:
                    filesUnarchivedCount += filesCount
                    if (filesListCount) {
                        progress = {
                            status: qsTr("Unpacking"),
                            unarchived: filesUnarchivedCount,
                            total: filesListCount,
                            percent: filesUnarchivedCount * 100.0 / filesListCount
                        }
                    }
                    break
            }
        }


        function onProcessFinished() {
            switch (process.mode) {
                case process.modeList:
                    installArchive()
                    break

                case process.modeUnarchive:
                    removeOldFiles()
                    break
            }
        }

        function listArchive() {
            mode = modeList
            filesListCount = 0
            process.start("unzip", ["-l", archive])
        }

        function installArchive() {
            FileIO.removeFile(deleteFiles)

            mode = modeUnarchive
            filesUnarchivedCount = 0
            process.start("unzip", ["-o", archive])
        }

        function removeOldFiles() {
            let files = FileIO.readTextFile(deleteFiles).split("\n")
            for (let file of files) {
                if (!file || file.startsWith("/") || file.indexOf("/../") !== -1) {
                    continue
                }

                FileIO.removeFile(outputDir + "/" + file.trim())
            }

            FileIO.removeFile(deleteFiles)

            archiveInstaller.finished()
        }
    }

    function install(archive) {
        progress = {
            status: qsTr("Checking"),
            unarchived: null,
            total: null,
            percent: 0
        }
        process.archive = archive
        process.listArchive()
    }


    function cancel() {
        process.terminate()
    }
}
